package com.guang.springbootmybatisbatchoperate.batch;

import org.apache.ibatis.session.ExecutorType;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 批处理操作类
 */
public class MapperBatchExecutor {
    private static final Logger logger = LoggerFactory.getLogger(MapperBatchExecutor.class);
    private SqlSessionTemplate sqlSessionTemplate;
    private final Integer batchExecuteSize = 500;

    public MapperBatchExecutor(SqlSessionTemplate sqlSessionTemplate) {
        Assert.state(ExecutorType.BATCH == sqlSessionTemplate.getExecutorType(), "sqlSessionTemplate的executor必须为batch类型");
        this.sqlSessionTemplate = sqlSessionTemplate;
    }

    @Transactional(rollbackFor = {Exception.class})
    public <T> int batchInsert(String insertStatement, List<T> parameters) {
        if (StringUtils.hasText(insertStatement) && !CollectionUtils.isEmpty(parameters)) {
            logger.info("需要批量插入条数:" + parameters.size());
            int i = 0;
            for(int n = parameters.size(); i < n; ++i) {
                this.sqlSessionTemplate.insert(insertStatement, parameters.get(i));
                if (i != 0 && i % this.batchExecuteSize == 0) {
                    sqlSessionTemplate.flushStatements();
                }
            }
            sqlSessionTemplate.flushStatements();
            return parameters.size();
        } else {
            throw new IllegalArgumentException("insertStatement或parameters不能为空");
        }
    }

    @Transactional(rollbackFor = {Exception.class})
    public <T> int batchUpdate(String updateStatement, List<T> parameters) {
        if (!StringUtils.hasText(updateStatement) && !CollectionUtils.isEmpty(parameters)) {
            logger.info("需要批量修改条数:" + parameters.size());
            int i = 0;
            for(int n = parameters.size(); i < n; ++i) {
                this.sqlSessionTemplate.update(updateStatement, parameters.get(i));
                if (i != 0 && i % this.batchExecuteSize == 0) {
                    sqlSessionTemplate.flushStatements();
                }
            }
            this.sqlSessionTemplate.flushStatements();
            return parameters.size();
        } else {
            throw new IllegalArgumentException("insertStatement或parameters不能为空");
        }
    }
}